package net.lgy.config;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Amazon S3客户端配置类
 * 用于创建和配置与S3兼容的存储服务客户端（本配置适配MinIO，也可用于AWS S3）
 * 基于AWS Java SDK构建，支持与所有兼容S3协议的对象存储服务交互
 */
@Configuration  // 标识为Spring配置类，容器启动时会加载此类并创建Bean
@Slf4j  // Lombok注解，提供日志功能，可通过log变量输出日志
public class AmazonS3Config {

    /**
     * 注入MinIO配置类
     * 包含连接MinIO所需的核心参数（访问地址、密钥等）
     * 配置参数通常在application.yml/properties中定义
     */
    @Autowired
    private MinioConfig minioConfig;


    /**
     * 创建并配置AmazonS3客户端实例
     * 该Bean将被Spring容器管理，其他组件可直接注入使用
     *
     * @return 配置完成的AmazonS3客户端对象
     */
    @Bean(name = "amazonS3Client")  // 定义Bean名称，方便按名称注入
    public AmazonS3 getClient() {
        // 1. 配置客户端连接参数
        ClientConfiguration config = new ClientConfiguration();
        // 设置通信协议：开发环境可用HTTP，生产环境强烈建议使用HTTPS
        // 注意：MinIO默认启用HTTPS需要配置证书，否则需显式开启HTTP支持
        config.setProtocol(Protocol.HTTP);

        // 设置连接超时时间（毫秒）
        // 建议根据网络环境调整，过短可能导致正常连接被误判为超时
        config.setConnectionTimeout(5000);

        // 启用Expect-Continue协议支持
        // 对于大文件上传，此配置可优化HTTP交互流程，减少无效请求
        config.setUseExpectContinue(true);


        // 2. 配置身份认证信息
        // 使用MinIO的访问密钥和秘密密钥创建AWS兼容的凭证对象
        // 这里的密钥需要在MinIO控制台提前创建，并赋予合适的操作权限
        AWSCredentials credentials = new BasicAWSCredentials(
                minioConfig.getAccessKey(),   // 访问密钥（Access Key）
                minioConfig.getAccessSecret() // 秘密密钥（Secret Key）
        );


        // 3. 配置服务端点（Endpoint）
        // 对于MinIO，此处填写MinIO服务的访问地址（如http://localhost:9000）
        // 对于AWS S3，无需手动设置，SDK会根据区域自动解析端点
        AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(
                minioConfig.getEndpoint(),       // MinIO服务地址
                Regions.US_EAST_1.name()         // 区域标识（MinIO可任意填任意有效值，AWS需填写实际区域）
        );


        // 4. 构建并返回S3客户端实例
        // 使用建造者模式配置客户端的各项参数
        return AmazonS3ClientBuilder.standard()
                .withClientConfiguration(config)                  // 应用连接配置
                .withCredentials(new AWSStaticCredentialsProvider(credentials))  // 应用身份认证
                .withEndpointConfiguration(endpointConfiguration)  // 应用端点配置
                // 启用路径风格访问（关键配置！）
                // 路径风格：http://endpoint/bucket/object
                // 虚拟主机风格：http://bucket.endpoint/object（MinIO默认不支持，需特殊配置）
                .withPathStyleAccessEnabled(true)
                .build();
    }

}
